package com.example.service.aboutUser.impl;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.vo.request.CreateRoleForm;
import com.example.vo.request.EditRoleDesForm;
import com.example.vo.request.NewRolePermission;
import com.example.vo.response.SystemPermissionDTO;
import com.example.vo.response.SystemRoleDTO;
import com.example.mapper.aboutUser.RoleMapper;
import com.example.mapper.aboutUser.RolePermissionRelationMapper;
import com.example.mapper.aboutUser.UserRoleRelationMapper;
import com.example.pojo.aboutUser.*;
import com.example.service.aboutUser.RolePermissionRelationService;
import com.example.service.aboutUser.RoleService;
import com.example.service.aboutUser.UserPermissionRelationService;
import com.example.vo.Result;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;


@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, SystemRole> implements RoleService{

    @Resource
    private RolePermissionRelationMapper rolePermissionRelationMapper;

    @Resource
    private RolePermissionRelationService rolePermissionRelationService;

    @Resource
    private UserRoleRelationMapper userRoleRelationMapper;

    @Resource
    private UserPermissionRelationService userPermissionRelationService;


    /**
     * 获取系统所有角色，及角色拥有的权限
     * 
     * @return 系统角色列表DTO
     */
    @Override
    public Result getAllRole() {
        LambdaQueryWrapper<SystemRole> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SystemRole::getRoleState, true)
                .eq(SystemRole::getIsDelete, false);

        List<SystemRole> roleList = super.list(lambdaQueryWrapper);

        List<SystemRoleDTO> roleDTOS = BeanUtil.copyToList(roleList, SystemRoleDTO.class);

        // 设置角色的权限
        for (SystemRoleDTO role : roleDTOS) {
            List<SystemPermission> permissions = this.rolePermissionRelationMapper.getPermissionsByRoleId(role.getId());

            role.setSystemPermissions(BeanUtil.copyToList(permissions, SystemPermissionDTO.class));
        }

        return Result.success(roleDTOS);
    }

    /**
     * 新增角色
     *
     * @param createRoleForm 新增角色表单，包含角色名称、描述
     * @return 是否新增成功
     */
    @Override
    public Result createRole(CreateRoleForm createRoleForm) {
        SystemRole systemRole = BeanUtil.copyProperties(createRoleForm, SystemRole.class);

        super.save(systemRole);

        return Result.success();
    }

    /**
     * 根据角色id获取角色所有权限
     *
     * @param roleId 角色id
     * @return 角色所有权限DTO
     */
    @Override
    public Result getPermissionsByRoleId(Integer roleId) {
        List<SystemPermission> permissions = this.rolePermissionRelationMapper.getPermissionsByRoleId(roleId);

        return Result.success(BeanUtil.copyToList(permissions, SystemPermissionDTO.class));
    }

    /**
     * 更新角色权限
     *
     * @param newRolePermission 包含角色id,角色新权限
     * @return 是否更新成功
     */
    @Override
    @Transactional
    public Result updateRolePermission(NewRolePermission newRolePermission) {

        // 角色新的权限，参数：id, permission[]
        List<SystemPermissionDTO> permissions = newRolePermission.getPermission();
        Integer roleId = newRolePermission.getRoleId();

        if(roleId == 8) {
            return Result.error("管理员角色无法修改！");
        }

        // 角色原来的权限
        List<SystemPermission> originRolePermissions = rolePermissionRelationMapper.getPermissionsByRoleId(roleId);

        // 删除原来的角色权限，参数：角色id
        LambdaQueryWrapper<RolePermissionRelation> rolePermissionRelationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        rolePermissionRelationLambdaQueryWrapper.eq(RolePermissionRelation::getRoleId, roleId);
        rolePermissionRelationService.remove(rolePermissionRelationLambdaQueryWrapper);

        List<RolePermissionRelation> rolePermissionRelations = new ArrayList<>();

        for (SystemPermissionDTO permission : permissions) {
            RolePermissionRelation rolePermissionRelation = new RolePermissionRelation();
            rolePermissionRelation.setRoleId(roleId);
            rolePermissionRelation.setPermissionId(permission.getId());

            rolePermissionRelations.add(rolePermissionRelation);
        }

        // 设置新的角色权限
        rolePermissionRelationService.saveBatch(rolePermissionRelations);

        // 查询所有拥有此角色id的用户
        List<User> users = userRoleRelationMapper.getUsersByRoleId(roleId);

        for (User user : users) {
            LambdaQueryWrapper<UserPermissionRelation> userPermissionRelationLambdaQueryWrapper = new LambdaQueryWrapper<>();

            // 删除原来此角色id对应的权限
            for (SystemPermission originRolePermission : originRolePermissions) {
                userPermissionRelationLambdaQueryWrapper.eq(UserPermissionRelation::getUserId, user.getId())
                        .eq(UserPermissionRelation::getPermissionId, originRolePermission.getId());
                userPermissionRelationService.remove(userPermissionRelationLambdaQueryWrapper);

                userPermissionRelationLambdaQueryWrapper.clear();
            }

            // 设置新的此角色id对应的权限
            for (SystemPermissionDTO permission : permissions) {
                UserPermissionRelation userPermissionRelation = new UserPermissionRelation();

                userPermissionRelation.setUserId(user.getId());
                userPermissionRelation.setPermissionId(permission.getId());

                try {
                    userPermissionRelationService.save(userPermissionRelation);
                }catch (Exception ignored) {}

            }
        }

        return Result.success();
    }

    /**
     * 修改角色描述信息
     *
     * @param editRoleDesForm 包含角色id,角色描述
     * @return 是否修改成功
     */
    @Override
    public Result updateRoleDescription(EditRoleDesForm editRoleDesForm) {
        LambdaUpdateWrapper<SystemRole> systemRoleLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        systemRoleLambdaUpdateWrapper.eq(SystemRole::getId, editRoleDesForm.getRoleId())
                .set(SystemRole::getRoleDescription, editRoleDesForm.getRoleDescription());

        super.update(systemRoleLambdaUpdateWrapper);

        return Result.success();
    }
}
